package com.ddx.common.util;

import java.text.*;
import java.util.*;

import com.google.common.base.Strings;

public class DateUtils {
    public final static String DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
    public final static SimpleDateFormat sDateTimeFormat = new SimpleDateFormat(DateTimeFormat);
    public final static SimpleDateFormat sTimeFormat = new SimpleDateFormat("HH:mm:ss");
    public final static SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    public final static SimpleDateFormat sSimpleDateFormat = new SimpleDateFormat("yyyyMMdd");
    public final static SimpleDateFormat wholeDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

    public static Date toDateTime(long ms) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(ms);
        return cal.getTime();
    }

    public static Date toDateTime(String dateString) {
        if (Strings.isNullOrEmpty(dateString))
            return null;

        try {
            return sDateTimeFormat.parse(dateString);
        } catch (Exception pe) {
            return null;
        }
    }

    public static Date toDate(String dateString) {
        if (Strings.isNullOrEmpty(dateString))
            return null;

        try {
            return sDateFormat.parse(dateString);
        } catch (Exception pe) {
            return null;
        }
    }

    public static String nowString() {
        return sDateTimeFormat.format(new Date());
    }

    public static String nowString(SimpleDateFormat df) {
        return df.format(new Date());
    }

    public static String toDateString(Date date) {
        if (date == null)
            return null;
        else
            return sDateFormat.format(date);
    }

    public static String toSimpleDateString(Date date) {
        if (date == null)
            return null;
        else
            return sSimpleDateFormat.format(date);
    }

    public static String toWholeDateString(Date date) {
        if (date == null)
            return null;
        else
            return wholeDateFormat.format(date);
    }

    public static String toDateTimeString(Date date) {
        if (date == null)
            return null;
        else
            return sDateTimeFormat.format(date);
    }

    public static String toString(Date date, SimpleDateFormat df) {
        if (date == null)
            return null;
        else
            return df.format(date);
    }

    public static Calendar toCalendar(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }

    public static int monthsBetween(Date dateStart, Date dateEnd) {
        Calendar calStart = Calendar.getInstance();
        calStart.setTime(dateStart);
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(dateEnd);

        return monthsBetween(calStart, calEnd);
    }

    public static int monthsBetween(Calendar calStart, Calendar calEnd) {
        int sYear = calStart.get(Calendar.YEAR);
        int sMonth = calStart.get(Calendar.MONTH);

        int eYear = calEnd.get(Calendar.YEAR);
        int eMonth = calEnd.get(Calendar.MONTH);

        return ((eYear - sYear) * 12 + (eMonth - sMonth));
    }

    public static int daysBetween(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        return daysBetween(cal1, cal2);
    }

    public static int daysBetween(Calendar cal1, Calendar cal2) {
        long time1 = cal1.getTimeInMillis();
        long time2 = cal2.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    public static int minBetween(Date date1, Date date2) {
        long time1 = date1.getTime();
        long time2 = date2.getTime();
        long between_min = (time1 - time2) / (1000 * 60);

        return Integer.parseInt(String.valueOf(between_min));
    }

    public static String daysBetweenString(Date date1, Date date2) {
        int dayPast = DateUtils.daysBetween(date1, date2);
        if (dayPast == 0)
            return "今天";
        else if (dayPast < 0)
            return String.format("%d天前", -dayPast);
        else
            return String.format("%d天后", dayPast);
    }

    public static Date getToday() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Calendar getTodayCalendar() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal;
    }

    public static Date getDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Calendar getDay(Calendar cal) {
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal;
    }

    public static Date getTomorrow() {
        return addDay(1);
    }

    public static Date getTomorrow(Date date) {
        return addDay(date, 1);
    }

    public static Date getYesterday() {
        return addDay(-1);
    }

    public static Date getYesterday(Date date) {
        return addDay(date, -1);
    }

    public static Date addMinute(Date date, int addMinute) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, addMinute);
        return cal.getTime();
    }

    public static Date addHour(Date date, int addHour) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR, addHour);
        return cal.getTime();
    }

    public static Date addDay(int addDay) {
        Calendar cal = getTodayCalendar();
        cal.add(Calendar.DATE, addDay);
        return cal.getTime();
    }

    public static Date addDay(Date date, int addDay) {
        if (date == null)
            return null;

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, addDay);
        return cal.getTime();
    }

    public static Date addMonth(Date date, int addMonth) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, addMonth);
        return cal.getTime();
    }

    public static Date getFirstDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        return getDay(cal).getTime();
    }

    public static Date getLastDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int value = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, value);
        return getDay(cal).getTime();
    }

    public static String getTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

    public static Date addHalfHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, 30);
        return calendar.getTime();
    }

    /*
     * return (dateStart < dt < dateEnd)
     */
    public static boolean inDate(Date dt, Date dateStart, Date dateEnd) {
        return (DateUtils.compareDate(dateStart, dt) && DateUtils.compareDate(dt, dateEnd));
    }

    /*
     * return (date1 < date2)
     */
    public static boolean compareDate(Date date1, Date date2) {
        return (date1.getTime() < date2.getTime());
    }

    /*
     * "yyyy-MM-dd HH:mm:ss" return (dateString1 < dateString2)
     */
    public static boolean compareDate(String dateString1, String dateString2) {
        try {
            Date date1 = sDateTimeFormat.parse(dateString1);
            Date date2 = sDateTimeFormat.parse(dateString2);
            return DateUtils.compareDate(date1, date2);
        } catch (Exception e) {
            return false;
        }
    }

    public static Date addDateByWorkDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        try {
            for (int i = 0; i < day; i++) {
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                if (checkHoliday(calendar)) {
                    i--;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return calendar.getTime();
    }

    public static boolean checkHoliday(Calendar calendar) throws Exception {
        // 判断日期是否是周六周日
        if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            return true;
        }
        // 判断日期是否是节假日
        /*
         * for (Calendar ca : holidayList) { if (ca.get(Calendar.MONTH) == calendar.get(Calendar.MONTH) && ca.get(Calendar.DAY_OF_MONTH) == calendar.get(Calendar.DAY_OF_MONTH) && ca.get(Calendar.YEAR) == calendar.get(Calendar.YEAR)) { return true; } }
         */
        return false;
    }

    public static Date toSimpleDate(String date) {
        if (Strings.isNullOrEmpty(date)) {
            return null;
        }
        try {
            return sSimpleDateFormat.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 两个时间相差距几个小时
     */
    public static long getDistanceTimes(Date date1, Date date2) {
        long day = 0;
        long hour = 0;
        try {
            long time1 = date1.getTime();
            long time2 = date2.getTime();
            long diff;
            if (time1 < time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            day = diff / (24 * 60 * 60 * 1000);
            hour = (diff / (60 * 60 * 1000) - day * 24) + day * 24;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hour;
    }

    /**
     * 加减某些天数
     * 
     * @param date
     * @param amount
     * @return
     */
    public static Date addDate(Date date, int amount) {
        if (date == null) {
            throw new NullPointerException();
        }
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, amount);
        return calendar.getTime();
    }

}
